package com.topc.code.judge.template;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.topc.problem.model.code.ExecuteCodeResponse;
import com.topc.problem.model.code.ExecuteMessage;
import com.topc.problem.model.code.JudgeInfo;
import com.topc.problem.model.enums.QuestionSubmitStatusEnum;

import java.io.File;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


public class CommonCodeSandboxTemplate
{
    /**
     * 把用户的代码保存为文件
     *
     * @param code           用户代码
     * @param globalCodePath 全局代码路径
     * @param fileName       文件名
     * @return
     */
    public File saveCodeToFile(String code, String globalCodePath, String fileName)
    {
        String userDir = System.getProperty("user.dir");
        String globalCodePathName = userDir + File.separator + globalCodePath;
        // 判断全局代码目录是否存在，没有则新建
        if (!FileUtil.exist(globalCodePathName))
        {
            FileUtil.mkdir(globalCodePathName);
        }

        // 把用户的代码隔离存放
        String userCodeParentPath = globalCodePathName + File.separator + UUID.randomUUID();
        String userCodePath = userCodeParentPath + File.separator + fileName;
        File userCodeFile = FileUtil.writeString(code, userCodePath, StandardCharsets.UTF_8);

        return userCodeFile;
    }

    /**
     * 整理输出结果
     * @param executeMessageList
     * @return
     */
    public ExecuteCodeResponse getOutputResponse(List<ExecuteMessage> executeMessageList)
    {
        List<String> outputList = new ArrayList<>();
        List<BigDecimal> timeList =new ArrayList<>();
        List<BigDecimal> memoryList =new ArrayList<>();
        // 取用时最大值，便于判断是否超时
        BigDecimal maxTime = BigDecimal.valueOf(0);
        BigDecimal maxMemory = BigDecimal.valueOf(0);
        ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();
        for (ExecuteMessage executeMessage : executeMessageList)
        {
            String errorMessage = executeMessage.getErrorMessage();
            if (StrUtil.isNotBlank(errorMessage))
            {
                executeCodeResponse.setMessage(executeMessage.getMessage());
                // 用户提交的代码执行中存在错误
                executeCodeResponse.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());
                executeCodeResponse.setMessage(errorMessage);
                break;
            }
            //保存当前输入样例对应的输出值
            outputList.add(executeMessage.getMessage());
            //记录当前最大运行时间
            BigDecimal time= BigDecimal.valueOf(executeMessage.getTime());
            timeList.add(time);
            if (time !=null){
                if (maxTime.compareTo(time) < 0){
                    maxTime=time;
                }
            }
            //记录当前最大内存
            BigDecimal memory = BigDecimal.valueOf(executeMessage.getMemory());
            memoryList.add(memory);
            if (memory !=null){
                //如果最大内存比该次内存小，刷新最大内存占用
                if (maxMemory.compareTo(memory) < 0){
                    maxMemory=memory;
                }
            }
        }
        //运行完成，整理结果
        if (outputList.size()==executeMessageList.size()){
            executeCodeResponse.setStatus(QuestionSubmitStatusEnum.SUCCEED.getValue());
            executeCodeResponse.setMessage("运行成功");
        }
        JudgeInfo judgeInfo = new JudgeInfo();
        judgeInfo.setTime(maxTime);
        judgeInfo.setMemory(maxMemory);
        executeCodeResponse.setOutputList(outputList);
        executeCodeResponse.setTimeList(timeList);
        executeCodeResponse.setMemoryList(memoryList);
        executeCodeResponse.setJudgeInfo(judgeInfo);
        return executeCodeResponse;
    }
    /**
     * 获取输出结果
     *
     * @param executeMessageList
     * @return
     */
//    public List<ExecuteCodeResponse> getOutputResponse(List<ExecuteMessage> executeMessageList)
//    {
//        List<ExecuteCodeResponse> executeCodeResponseList = new ArrayList<>();
//        // 取用时最大值，便于判断是否超时
//        long maxTime = 0;
//        long maxMemory = 0;
//        for (ExecuteMessage executeMessage : executeMessageList)
//        {
//            ExecuteCodeResponse executeCodeResponse = new ExecuteCodeResponse();
//            String errorMessage = executeMessage.getErrorMessage();
//            if (StrUtil.isNotBlank(errorMessage))
//            {
//                executeCodeResponse.setMessage(executeMessage.getMessage());
//                // 用户提交的代码执行中存在错误
//                executeCodeResponse.setStatus(QuestionSubmitStatusEnum.FAILED.getValue());
//                executeCodeResponse.setJudgeInfo(new JudgeInfo(errorMessage, null, null));
//                executeCodeResponseList.add(executeCodeResponse);
//                break;
//            }
//            JudgeInfo judgeInfo = new JudgeInfo();
//            Long time = executeMessage.getTime();
//            Long memory = executeMessage.getMemory();
//            judgeInfo.setTime(time);
//            judgeInfo.setMemory(memory);
//            executeCodeResponse.setJudgeInfo(judgeInfo);
//            executeCodeResponseList.add(executeCodeResponse);
//        }
//        return executeCodeResponseList;
//    }

    /**
     * 删除文件
     *
     * @param userCodeFile
     * @return
     */
    public boolean deleteFile(File userCodeFile)
    {
        if (userCodeFile.getParentFile() != null)
        {
            String userCodeParentPath = userCodeFile.getParentFile().getAbsolutePath();
            boolean del = FileUtil.del(userCodeParentPath);
            System.out.println("删除" + (del ? "成功" : "失败"));
            return del;
        }
        return true;
    }

}
